我使用gemini提取出了老师视频中展示的文档,非常好。因为老师确实没有给文档,blog里面也搜不到,幸好有了AI,帮我很大的忙。

配置安装 Setup

  1. Install NodeJS and Database 前提是要安装nodejs和某种数据库,因为prisma通常是为关系型数据库构建的,所以NoSQL这些大部分都不能支持,只支持MongoDB。我按照老师的要求,安装了postgresql。

  2. npm init -y ,初始化项目。 npm i --save-dev prisma typescript ts-node @types/node nodemon , Install dependencies

  3. Create tsconfig.json

    这个是配置typescript相关的。

  4. npx prisma init --datasource-provider postgresql , Initial Prisma project

  5. Connect Database

    a. Install VSCode extension for Prisma

    b. Also talk about auto formatting and npx prisma format

    这里需要重点讲解一下,datasource db指的是Prisma orm该怎么样连接到数据库管理系统,provider指的是数据库管理系统的类型,可以是mysqlsqlite等等,url指的是连接数据库管理系统的哪一个数据库。

    在步骤4执行之后,会生成schema.prisma文件和.env文件,在.env文件里面,有一个DATABASE_URL的变量,这里存放的是数据库的地址。这个地址可以是本地数据库的地址,也可以是云服务器中数据库的地址。

    image-20251023105826226

    generator的作用是定义代码生成规则,provider指定用哪一个生成器,output自定义生成文件的输出目录。因为prisma的核心是“基于schema自动生成代码”,而generator就是“告诉prisma”要生成什么,怎么生成,生成到哪里“的关键配置。

    只有这样配置了,在代码中才能使用PrismaClient,来方便的操作数据库。

    url的格式是:postgresql://用户名:密码@主机:端口/数据库名,我的本地用户名默认是postgres,密码是123456,主机是localhost,端口是5432,数据库需要新建,打开powershell,输入psql -h localhost -p 5432 -U postgres,输入密码123456,然后输入create database prisma,这样就生成了一个名称为prisma的数据库。

    那么这里的url就写成这样DATABASE_URL="postgresql://postgres:123456@localhost:5432/prisma?schema=public",这里的?schema=public,它的意思是告诉 Prisma(或其他工具):默认使用 public 这个 schema 来查找表和执行查询。这涉及到postgresql的表结构,和MySQL是不一样的,先不用管。

    image-20251023113721320

    schema.prisma
    prisma generate
    generator 配置
    生成 Prisma Client
    ../generated/prisma/index.js + 类型
    在代码中使用: `new PrismaClient`

    image-20251023105930064

  6. Create User Schema with name

  7. npx prisma migrate dev --name init , Create/Run migration。这一步是为了将定义的model迁移到数据库中去,dev表示只在开发环境做这件事,--name init表示为这次操作设置名称,方便以后查看。 这一步执行之后,会在prisma文件夹里面生成一个migrations文件夹,里面就是迁移文件,这些文件将与postgresql交互并进行用户指定的修改。 与此同时,也对Prisma client进行了更新,这样使用prisma client的时候,就能够用到最新的数据库。 image-20251023114555093

  8. npm install @prisma/client - Install Client (Talk about how this also generates the client as well for us and how this generation happens every time you migrate as well and how you can create this generation your self with npx prisma generate)

     

    创建一个script.ts文件,就可以写代码了。

  9. await prisma.user.create({ data: { name: "Sally" } }) - Create new user

  10. await prisma.user.findMany() - Get all users

 

Schema

Data Sources

  1. Can only have one datasource in your database
  2. The provider represents what database to use
  3. The url represents the URL of the database
  4. Should store the URL in .env to avoid exposing database secrets and to make it easy to change from dev to production

Generators

  1. Must have at least one generator but can have more than one

  2. The provider represents what generator to use

    a. This can be any NPM library such as a GraphQL generator

Models

  1. Models represent all the information about your database such as tables, columns, enums, etc.
  2. Each model is represented by a number of fields

Fields

  1. Fields are composed of a name, type, and optional type modifiers and attributes

FieldTypes

  1. String
  2. Boolean
  3. Int
  4. BigInt
  5. Float-能不用就不用,基本被Decimal取代了
  6. Decimal
  7. DateTime-使用类型转换来指定具体类型
你想要的 PostgreSQL 类型Prisma 写法(强烈推荐)说明(精度 / 时区)推荐指数
timestamp with time zone(最推荐)DateTime @db.Timestamptz保存 UTC 时间,带时区无关,精度 6 位(微秒)5 stars
timestamp without time zoneDateTime @db.Timestamp保存本地时间,不带时区,容易踩坑2 stars
timestamptz(简写,同第 1 种)DateTime(不写任何 @db 也行)Prisma 默认就是 timestamptz!5 stars
date(只存日期,不带时间)DateTime @db.Date相当于 2025-12-05,不带时间和时区4 stars
time(只存时间,不带日期)DateTime @db.Time13:14:15,精度到微秒3 stars
timetz(带时区的时间)DateTime @db.TimeTz很少用1 star
  1. Json-如果使用的是postgresql,那么prisma会自动设置为JSONB类型
  2. Bytes-存储文件哈希、加密 token、二进制小数据
  3. Reference to another table (Post)

基本语法:

最重要的三个参数:

参数类型必填?放在哪一边?说明与取值
nameString(字符串字面量)选填(但强烈建议写上)两边都要写(且相同)关系名字,用于消除歧义;迁移时保持关系稳定;精准include/select。
fieldsString[](字段名数组)必须(有外键的一方)外键所在的一方(多的一方)指明本模型里哪个字段是外键
referencesString[](字段名数组)必须(有外键的一方)外键所在的一方指向对端模型的哪个字段(通常是 @id 或 @@id)

这里的name可以用于精准include/select,这种需求在项目中是很常见的:

在多对多关系中,指定name参数,prisma会用这个name为我们创建一个中间表。

多对多关系@relation 指令不需要显式地定义 fieldsreferences 参数。

解释:

  • @relation("Enrollment") 中的 name 是 "Enrollment"。这意味着 Prisma 会为 StudentCourse 之间的多对多关系创建一个中间表,名称会是 Enrollment
  • 通过使用 name,我们可以明确中间表的名称,而不依赖 Prisma 默认的命名规则。

查询:


如果两个关系都没写 name,include 里只能写 posts,要么全拿,要么全不拿,完全无法分开。

一、什么时候可以不写 @relation?(最常见的情况)

结论:只要关系是「有外键的一方」写了 fields 和 references,另一方(User)可以完全不写 @relation,Prisma 自动推断,100% 正常工作。 这是目前 90% 项目都在用的最简写法。

二、什么时候必须写 @relation?(4 种硬性场景)

场景必须写 @relation 的原因正确写法示例
1. 自关联(同一个表里关联自己)不写会报错 “Ambiguous relation”见例子1
2. 一对多双向,但两边外键字段名不一致Prisma 无法自动匹配见例子2
3. 一个模型被多个关系引用(多对一多条)Prisma 不知道 Post[] 对应哪条关系见例子3
4. 多对多显式关系(中间表) 必须写 name 来配对

三、四大场景详细写法

场景1:自关联(粉丝、关注、上下级、树形评论)

关键:两边都用同一个名字 "FollowRelation",不然会报错。

场景2:外键字段名不是默认的 authorId

场景3:一个模型被多个关系引用(最容易踩坑!)

不写 name 的话 Prisma 会报:Error: Ambiguous relation on model User.posts

场景4:显式多对多(中间表自己控制)

Field Type Modifiers

符号就下面两个,另外还有两个方法。

  1. []

    a. Turns the column into a list. When used on a reference type it creates all needed foreign keys and such

    b. Can only be used on scalar types if the DB supports it

  2. ?

    a. Makes a field optional

    b. Cannot be used with []

修饰符写法位置含义数据库表现(PostgreSQL)常用场景
?放在类型后面可选字段(可为 null)nullable = true头像、昵称、手机号、描述等非必填字段
[]放在类型后面数组(List)text[]、int4[]、timestamptz[] 等标签、角色列表、图片数组、爱好等
@default()字段属性默认值DEFAULT ...状态、积分、排序、是否启用等
@updatedAt字段属性自动更新为当前时间ON UPDATE NOW()任何需要记录最后修改时间的字段

Field Attributes

  1. Attributes have two levels

    a. Field attributes apply to one field @

    b. Block attributes apply to the entire block @@

  2. @id

    a. All tables must have an id field or have a unique field

    b. Can be combined with @default

    i. autoincrement()-这个在postgresql里面就是serial类型了。

    ii. uuid()

    iii. cuid()-prisma推荐使用的id,就用这个

  3. @@id

    a. Used to create composite ids @@id([FirstName, LastName])

  4. @default

    a. Can be passed a static value or a function such as now()

  5. @unique - Makes a field unique

  6. @@unique - Makes a combination of fields unique @@unique(authorId, postId)

  7. @@index - Create index on one or more fields @@index(authorId, postId)

  8. @updatedAt - Automatically sets a field to the current time when you update the row

  9. @relation

    a. The fields with relation types are not actually in the db

    b. One To Many

    c. One To One

    d. Many To Many

    e. The @relation field must take a field and references value.

    i. The field points to the field on the current model

    ii. The references points to the field on the other model the field value references

    f. If you have multiple relations on the same model you need to pass a name to the references attribute to disambiguate them

完全列表(官方所有字段属性,一共就这些)

分类属性名称示例
主键@id, @@id([]) 
唯一约束@unique, @@unique([]) 
默认值@default(), @updatedAt 
数据库映射@map(), @@map() 
数据库类型@db.Xxx(所有 PostgreSQL 类型都支持)@db.Timestamptz, @db.Uuid, @db.VarChar(100)
索引@@index([]), @@index([], type: Xxx)GIN / Hash / Brin / Gist
全文搜索@@fulltext([]) 
关系@relation() 
忽略字段@ignore 
原生默认@default(dbgenerated("...")) 

举例说明:

频率属性写法作用典型值 / 示例必背程度
1@id声明主键(单字段)@id5 stars
2@@id([field1, field2])复合主键@@id([tenantId, id])5 stars
3@unique单字段唯一约束email String @unique5 stars
4@@unique([field1, field2])复合唯一约束@@unique([tenantId, email])5 stars
5@default(value)默认值@default(cuid())、@default(now())、@default(0)、@default(true)、@default([])、@default("{}")5 stars
6@updatedAt自动维护更新时间updatedAt DateTime @updatedAt5 stars
7@relation(...)关系字段(前面已详细讲)见前文5 stars
8@map("column_name")自定义数据库列名username String @map("user_name")4 stars
9@@map("table_name")自定义表名@@map("users"4 stars
10@db.Type强制指定 PostgreSQL 底层类型@db.Timestamptz、@db.VarChar(50)、@db.JsonB、@db.Date、@db.Uuid4 stars
11@@index([field])单字段索引@@index([email])4 stars
12@@index([field1, field2])复合索引@@index([tenantId, createdAt])4 stars
13@@index([field], type: Gin)GIN 索引(用于数组、jsonb、全文搜索)@@index([tags], type: Gin)、@@index([metadata], type: Gin)4 stars
14@@index([field], type: Hash)Hash 索引(只适合 = 查询)@@index([status], type: Hash)2 stars
15@@index([field], type: Brin)BRIN 索引(超大表时间序列)@@index([createdAt], type: Brin)2 stars
16@ignore完全忽略这个字段(不映射到数据库)@ignore(极少用)1 star
17@default(dbgenerated("sql"))使用数据库原生默认表达式@default(dbgenerated("gen_random_uuid()"))3 stars
18@@fulltext([title, content])PostgreSQL 原生全文搜索索引@@fulltext([title, content])3 stars

Enums

如果使用的是postgresql,推荐使用postgresql原生enums,就是在postgresql数据库里面定义enums。然后在model定义的时候使用即可。

不推荐使用prisma的方式来定义enums,就是在schema.prisma里面不要定义enums。可以搜一下为什么,这里给一个理由:给已有枚举加一个新状态 → Prisma Migrate 直接 drop + recreate 整个 enum 类型,后果就是依赖这个 enum 的所有表都要重建 → 几千万行的大表锁表 40 分钟~3 小时,业务直接宕机。

而在postgresql原生里面进行修改,几乎没有什么影响,这是实际经验教训。

Possible Finished Schema

 

Client

  1. Automatically connects when you run the first query
  2. Automatically disconnects when process ends
  3. Manages connection pool so only ever need one instance of the client

先记住下面最简单的操作,复杂操作查询文档即可,不要连最简单的操作都记不住。

Create

  1. create

    一对一、多对一新增使用connect来关联。

  2. createMany

Read

就记住这三个,不要嫌少,用的最多的就是这三种方法。

  1. findUnique - Can also include/select

    id@unique 字段或 @@unique / @@id 组合查一条记录;

  2. findFirst - Same as findMany but only gets first result

    条件不是 schema 中的唯一键(例如多字段组合但没加 @@unique,或复杂过滤);

  3. findMany - Can also select/include

    a. distinct - Can do distinct queries

    b. take / skip - Can do pagination

    c. orderBy - Can do sorting

Basic Filtering 基本过滤条件

where条件:

include/select方式:

聚合、统计、分组:

Relation Filtering 关联过滤

简单案例:

关键词含义对应 SQL 感觉
some至少一条EXISTS / IN
every全部满足NOT EXISTS(不满足的)
none一条都不NOT EXISTS
is对端本身满足内层 WHERE
isNot对端本身不满足内层 WHERE + NOT

Update

总体原则是先使用where条件,然后使用data更新值。

  1. update - Can also include/select

    a. Only updates 1 record

    b. Must include data and where

    ①基础更新(单表)

    ②一对多:修改文章标题 + 同时关联/取消关联作者

    ③更复杂的操作:多对多、upsert方法,用的时候查询即可。

Number Operations

数字操作,感觉不实用。

  1. increment

  2. decrement

  3. multiply

  4. divide

Delete

  1. delete - Can also select/include

    a. Only deletes 1 record

  2. deleteMany - Can also select/include

    a. Only deletes 1 record

收集资料

@@@ 开头属性

Prisma 中所有以 @@@ 开头的东西都叫 Attributes(属性),可以作用于:

下面给你一个 最完整、最清晰、业务开发最常用的列表。(已按用途分类,不用背,查表即可)

一、字段级属性(Field Attributes)——以 @ 开头

用于 字段(column)级别 的功能,比如主键、默认值、映射等。

1. 主键 & 唯一性

属性作用
@id将字段设置为主键
@unique设置字段为唯一索引
@@id([])复合主键(表级)→ 用 @@,但属于 ID 类

2. 默认值 / 自动更新

属性作用
@default(value)字段默认值,如字符串、数字、布尔、函数
@default(now())时间戳默认值
@default(uuid())生成 UUID
@default(cuid())生成 cuid(prisma规范,强烈推荐使用)
@updatedAt每次更新记录时自动更新该字段

3. 关系(Relation)

属性作用
@relation()定义关系,指定 foreign key 字段和引用字段

例:

4. 映射(Mapping)

属性作用
@map("column_name")把 Prisma 字段映射到数据库列名
@@map("table_name")映射模型名到数据库表(表级)

5. 类型转换(原生数据库类型)

属性作用
@db.VarChar(255)指定数据库实际类型(适配 PostgreSQL, SQLite, MySQL 等)

二、模型级属性(Model Attributes)——以 @@ 开头

用于 模型(表)级别 的功能,比如复合索引、表名映射等。

6. 表级映射(Mapping)

属性作用
@@map("table_name")映射 Prisma 模型到数据库表

7. 索引(Index)

属性作用
@@index([field1, field2])普通索引
@@unique([field1, field2])复合唯一索引

8. 复合主键

属性作用
@@id([field1, field2])设置复合主键

注意:复合主键不能和 @id 共存。

9. 关系名称(Relation Names)

一般用于双向关系中的自引用模型:

虽然写在 @relation 里,但属于模型关系配置范畴。

完整总结表(最常用)

字段级(@

属性用途
@id主键
@unique唯一约束
@default()默认值
@updatedAt自动更新时间
@relation()外键、关系
@map()字段映射到数据库列
@db.*数据库原生类型

模型级(@@

属性用途
@@map()模型映射到数据库表
@@index()索引
@@unique()复合唯一
@@id()复合主键